home *** CD-ROM | disk | FTP | other *** search
Wrap
//---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- // // Filename : opengl.cpp // Description : Member definitions for OpenGL Class // Author : Marnich van Rensburg (2002) // //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- #include "opengl.h" //---------------------------------------------------------------------------------------- // Description : Class Constructor - Initialize class data members //---------------------------------------------------------------------------------------- OpenGL :: OpenGL() { hDC = NULL; // GDI Device Context hRC = NULL; // Rendering Context hWnd = NULL; // Window Handle FullScreen = true; // Sets screen mode to fullscreen by default //Set Lights Data LightAmbient[0] = 1.0f; LightAmbient[1] = 1.0f; LightAmbient[2] = 1.0f; LightAmbient[3] = 1.0f; LightDiffuse[0] = 1.0f; LightDiffuse[1] = 1.0f; LightDiffuse[2] = 1.0f; LightDiffuse[3] = 1.0f; LightPosition[0] = 0.0f; LightPosition[1] = 0.0f; LightPosition[2] = 1.0f; LightPosition[3] = 1.0f; }// OpenGL //---------------------------------------------------------------------------------------- // Description : Displays an error message box containing the passed message //---------------------------------------------------------------------------------------- void OpenGL :: ErrorMsg(char *msg) { MessageBox(NULL, msg, "ERROR", MB_OK | MB_ICONEXCLAMATION); }// ErrorMsg //---------------------------------------------------------------------------------------- // Description : Initialize OpenGL settings //---------------------------------------------------------------------------------------- bool OpenGL :: InitGL() { glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Background Color glClearDepth(1.0f); // Depth Buffer Setup LoadFont(); //Init Font //Perspective glDepthFunc(GL_LEQUAL); // Type of Depth Testing glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Perspective Calculations // Load Textures if (!LoadGLTextures()) return false; glEnable(GL_TEXTURE_2D); // Enable Texture Mapping glDisable(GL_DEPTH_TEST); // Turn Depth Testing Off //Transparency glDisable(GL_BLEND); // Turn Blending On glColor4f(1.0f, 1.0f, 1.0f, 0.5f); // Full Brightness. 50% Alpha glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Set The Blending Function For Translucency //Lights glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light glEnable(GL_LIGHT1); // Enable Light One glEnable(GL_LIGHTING); //init stars float t_x, t_y; for(int n = 0; n < NUMBER_OF_STARS; n++) { t_x = t_y = 0.0f; while(t_x == 0.0f) t_x = (float)(rand() % 50) - 25.0f; while(t_y == 0.0f) t_y = (float)(rand() % 50) - 25.0f; StarField[n].x = t_x; StarField[n].y = t_y; }//for return true; }// InitGL void OpenGL :: RenderStart() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer glEnable(GL_LIGHTING); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); // Enable Texture Mapping glLoadIdentity(); }// RenderStart //---------------------------------------------------------------------------------------- // Description : Dummy function (not implemented) //---------------------------------------------------------------------------------------- void OpenGL :: RenderEnd() { return; }// RenderEnd //---------------------------------------------------------------------------------------- // Description : Renders "TETRON" on the screen //---------------------------------------------------------------------------------------- void OpenGL :: RenderGameTitle(float v_x, float v_y) { glEnable(GL_LIGHTING); glLoadIdentity(); glTranslatef(v_x, v_y, -10.0f); glBindTexture(GL_TEXTURE_2D, Texture[11]); glBegin(GL_QUADS); glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 2.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 2.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glEnd(); }// RenderGameTitle //---------------------------------------------------------------------------------------- // Description : Types "Game Over" on the screen //---------------------------------------------------------------------------------------- void OpenGL :: RenderGameOver(char Mode[4]) { int n = 0; SetTextBase(32); static char Str[] = "GAME OVER"; static int cn = 0; static float B[9] = {0.0f}; if(Mode == "New") { cn = 0; for(n = 0; n < 9; n++) B[n] = 0.0f; return; }//if if(B[cn] < 1.0f) { B[cn] += 0.025f; }else{ if(cn < 8) { cn++; if(SoundActive) PlaySound("data/gameover.wav", NULL, SND_ASYNC);// Play sound } }//if for(n = 0; n <= cn; n++) { glColor3f(B[n], B[n], B[n]); Print(176 + (n * 32), 240, "%c", Str[n]); }//for }//RenderGameOver //---------------------------------------------------------------------------------------- // Description : Shows the next piece //---------------------------------------------------------------------------------------- void OpenGL :: RenderNextPreview(Tetramino& ref_TetNext) { //Draw Tetramino glLoadIdentity(); glTranslatef(-14.0f, 7.5f, -30.0f); for (char ny = 0; ny < 4; ny++) { for (char nx = 0; nx < 4; nx++) { glTranslatef(1.0f, 0.0f, 0.0f); if(ref_TetNext.GetMatrix(nx, ny) != 0) DrawFace(ref_TetNext.Type); }//for glTranslatef(-4.0f, -1.0f, 0.0f); }//for //Draw Preview Box glLoadIdentity(); glTranslatef(-2.5f, 0.5f, -5.0f); glBindTexture(GL_TEXTURE_2D, Texture[9]); glBegin(GL_QUADS); glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glEnd(); //Draw Preview arrow glTranslatef(1.0f, 0.0f, 0.0f); glBindTexture(GL_TEXTURE_2D, Texture[10]); glBegin(GL_QUADS); glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.25f, 0.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.25f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glEnd(); }// RenderNextPreview //---------------------------------------------------------------------------------------- // Description : Shows arrows depending on the rotation direction of the container //---------------------------------------------------------------------------------------- void OpenGL :: RenderRotationArrows(unsigned char v_UserAction) { static float B[2] = {0.0f}; // Store the brightness level of arrows static float RA = 0.0f; // Store current rotation angle of arrows switch(v_UserAction) // Identify which user action should be shown { case 39: {if(B[0] < 1.0f) B[0] += 0.5f; break;} // Right Arrow case 37: {if(B[1] < 1.0f) B[1] += 0.5f; break;} // Left Arrow }//switch // Draw the left and right arrows glDisable(GL_LIGHTING); glEnable(GL_BLEND); glDisable(GL_TEXTURE_2D); // Draw Right Arrow glLoadIdentity(); glTranslatef(8.0f, 0.0f, -30.0f); glRotatef(RA, 1.0f, 0.0f, 0.0f); glBegin(GL_TRIANGLES); glColor3f(B[0], B[0], B[0]);glVertex3f( 2.0f, 0.0f, 0.0f); glColor3f(0.0f, 0.0f, 0.0f);glVertex3f(-1.0f, 1.0f, 0.0f); glColor3f(B[0], B[0], B[0]);glVertex3f( 0.0f, 0.0f, 0.0f); glColor3f(B[0], B[0], B[0]);glVertex3f( 2.0f, 0.0f, 0.0f); glColor3f(0.0f, 0.0f, 0.0f);glVertex3f(-1.0f,-1.0f, 0.0f); glColor3f(B[0], B[0], B[0]);glVertex3f( 0.0f, 0.0f, 0.0f); glEnd(); // Draw Left Arrow glLoadIdentity(); glTranslatef(-8.0f, 0.0f, -30.0f); glRotatef(RA * -1.0f, 1.0f, 0.0f, 0.0f); glBegin(GL_TRIANGLES); glColor3f(B[1], B[1], B[1]);glVertex3f(-2.0f, 0.0f, 0.0f); glColor3f(0.0f, 0.0f, 0.0f);glVertex3f( 1.0f, 1.0f, 0.0f); glColor3f(B[1], B[1], B[1]);glVertex3f( 0.0f, 0.0f, 0.0f); glColor3f(B[1], B[1], B[1]);glVertex3f(-2.0f, 0.0f, 0.0f); glColor3f(0.0f, 0.0f, 0.0f);glVertex3f( 1.0f,-1.0f, 0.0f); glColor3f(B[1], B[1], B[1]);glVertex3f( 0.0f, 0.0f, 0.0f); glEnd(); glEnable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_BLEND); RA += 2.0f; // Inc. current angle by 5 // Perform slow decay of arrow B if(B[0] > 0.0f) B[0] -= 0.01f; // Decrease Brightness of left arrow if(B[1] > 0.0f) B[1] -= 0.01f; // Decrease Brightness of right arrow }// RenderRotationArrows //---------------------------------------------------------------------------------------- // Description : Draws a textured quad based on type value //---------------------------------------------------------------------------------------- void OpenGL :: DrawFace(char v_Type) { glBindTexture(GL_TEXTURE_2D, Texture[v_Type]); glBegin(GL_QUADS); // Front Face glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f,-0.5f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f,-0.5f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f, 0.5f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.0f); glEnd(); }// DrawFace //---------------------------------------------------------------------------------------- // Description : Draws the container object //---------------------------------------------------------------------------------------- void OpenGL :: RenderContainer(Container& r_Con) { glColor3f(1.0f, 1.0f, 1.0f); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glLoadIdentity(); // Reset The View glTranslatef( r_Con.x, r_Con.y + (float)(CON_HEIGHT / 2), r_Con.z); //Set position glRotatef(r_Con.GetRotation() - 20.0f, 0.0f, 1.0f, 0.0f); //y rotate container // Draw Container Cells Top to Bottom, Left to Right for (char cy = 0; cy != CON_HEIGHT; cy++) //loop through the vertical cells { glTranslatef( 0.0f, -1.0f, 0.0f); //Move 1 row down for (char cx = 0; cx != CON_WIDTH; cx++) //loop through the horizontal cells { glRotatef(10.0f, 0.0f, 1.0f, 0.0f); //Rotate 10 degrees to right glTranslatef( 0.0f, 0.0f, CON_RADIUS); //Move out to container surface DrawFace(r_Con.GetMatrix(cx, cy)); //Draw the cell face glTranslatef( 0.0f, 0.0f, -CON_RADIUS); //Move back to center }//for }//for }// RenderContainer //---------------------------------------------------------------------------------------- // Description : Draws the start screen //---------------------------------------------------------------------------------------- void OpenGL :: RenderStartScreen(Top10& ref_HS) { RenderGameTitle(-1.0f, 2.0f); int n = 0; static char Str[] = "Press SPACE to start#coded by Marnich van Rensburg"; static int cn = 0; static int letter_n = 0; static int row, col = 0; static Timer TextTimer; static int str_len = sizeof(Str) - 1; static float B[100] = {0.5f}; glColor3f(1.0f, 0.8f, 0.0f); //Highscore Table Col Headings Print(230, 210, "* TOP 10 SCORES *"); glColor3f(0.7f, 0.7f, 0.3f); Print(90, 230, "No"); Print(130, 230, "Name"); Print(370, 230, "Lines"); Print(430, 230, "Level"); Print(490, 230, "Score"); //display table entries int tl_row = 0; float lcolor = 1.0f; for(n = 0; n < 10; n++) { tl_row = 250 + ((n + 1) * 15); lcolor = 1.0f - ((float)(n+1) / 20.0f); glColor3f(0.0f, 0.0f, lcolor); if(n<9) Print(105, tl_row, "%i", n + 1); else Print(95, tl_row, "%i", n + 1); Print(130, tl_row, "%s", ref_HS.List[n].Name); Print(370, tl_row, "%u", ref_HS.List[n].Lines); Print(430, tl_row, "%u", ref_HS.List[n].Level); Print(490, tl_row, "%u", ref_HS.List[n].Score); }//for if(TextTimer.CheckFreq(90) && letter_n < str_len) { cn++; B[cn] = 0.5f; letter_n++; if(Str[letter_n] != '#') if(SoundActive) PlaySound("data/start.wav", NULL, SND_ASYNC);// Play sound } SetTextBase(32); row = 17; col = 21; for(n = 0; n <= letter_n; n++) { if(B[n] < 1.0f) B[n] += 0.001f; glColor3f(B[n], B[n], B[n]); if(Str[n] == '#') { row = 47; col = 33; }else{ col++; Print((col * 10), (row * 10), "%c", Str[n]); } }//for }//end RenderStartScreen void OpenGL :: DebugVal(float v_Val) { SetTextBase(32); glColor3f(1.0f, 1.0f, 1.0f); Print(40, 40, "Val = %f", v_Val); } //---------------------------------------------------------------------------------------- // Description : Draws the container object //---------------------------------------------------------------------------------------- void OpenGL :: RenderHighScoreScreen(char v_Name[25], char v_CursorPos, unsigned int v_Score) { static float CursorCol = 0.0f; CursorCol += 0.025f; if(CursorCol >= 1.0f) CursorCol = 0.0f; SetTextBase(32); glColor3f(1.0f, 1.0f, 1.0f); Print(210, 200, " * New Top 10 Score *"); Print(210, 230, " %i", v_Score); Print(210, 260, "Please enter your name:"); for(int n = 0; n < 23; n++) Print(210 + (n * 10), 280, "%c", v_Name[n]); glColor3f(CursorCol, CursorCol, CursorCol); Print(210 + (v_CursorPos * 10), 285, "_"); }//end RenderHighScoreScreen //---------------------------------------------------------------------------------------- // Description : Draws a graph line //---------------------------------------------------------------------------------------- void OpenGL :: DrawGraphLine(float v_x, float v_y, float v_z, float v_Length) { glDisable(GL_LIGHTING); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); glLoadIdentity(); glTranslatef(v_x, v_y, v_z); v_Length /= 12.5f; glBegin(GL_QUADS); glColor3f(0.2f, 0.2f, 0.2f); glVertex3f(0.0f, -0.2f, 0.0f); glColor3f(0.7f, 0.7f, 0.7f); glVertex3f(v_Length, -0.2f, 0.0f); glColor3f(0.9f, 0.7f, 0.7f); glVertex3f(v_Length, 0.2f, 0.0f); glColor3f(0.3f, 0.6f, 0.3f); glVertex3f(0.0f, 0.2f, 0.0f); glEnd(); glColor3f(1.0f, 1.0f, 1.0f); glEnable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_BLEND); glLoadIdentity(); glTranslatef(v_x, v_y, v_z); glBindTexture(GL_TEXTURE_2D, Texture[13]); glBegin(GL_QUADS); glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f,-0.4f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(8.0f,-0.4f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(8.0f, 0.4f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 0.4f, 0.0f); glEnd(); }//end DrawGraphLine //---------------------------------------------------------------------------------------- // Description : Renders game stats on screen (score etc.) //---------------------------------------------------------------------------------------- void OpenGL :: RenderGameStats(GameStats& ref_Stats) { static unsigned int VisScore = 0; // The score currently shown, not actual ness. game score static float VisAvg[7] = {0.0f}; // The avg currently shown //Ajust dif. between actual game score and the score shown if (ref_Stats.Score > VisScore) VisScore += (int)((ref_Stats.Score - VisScore) / 10); if ((ref_Stats.Score < VisScore) && (VisScore > 0)) VisScore = ref_Stats.Score; glColor3f(1.0f, 1.0f, 1.0f); SetTextBase(32); Print(430,100,"SCORE [ %2i ]",(int)VisScore); Print(430,130,"LINES [ %2i ]",(int)ref_Stats.Lines); Print(430,160,"LEVEL [ %2i ]",(int)ref_Stats.Level); float TetAvg = 0.0f; glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); //Draw tetramino stats for(int type = 0; type != 7; type++) { glLoadIdentity(); glTranslatef(7.0f, -2.0f - (float)(type * 1.2f), -32.0f); DrawFace(type + 1); //prevent division by zero if(ref_Stats.TetTotal) TetAvg = ((float)ref_Stats.TetTypeCount[type] / (float)ref_Stats.TetTotal) * 100.0f; // calc average else TetAvg = 0.0f; //Print(470,282 + (type * 22)," [ %2i%% ]",(int)TetAvg); if(TetAvg > VisAvg[type]) VisAvg[type] += 0.2f; if(TetAvg < VisAvg[type]) VisAvg[type] -= 0.2f; DrawGraphLine(8.5f, -2.0f - (float)(type * 1.2f), -32.0f, VisAvg[type]); }//for }// RenderGameStats //---------------------------------------------------------------------------------------- // Description : Displays a rotating arrow for the lenght of the drop //---------------------------------------------------------------------------------------- void OpenGL :: RenderDropArrow(char v_Start, char v_End, bool v_DropState) { static float B = 0.0f; // Store the brightness level of arrow static float Angle = 0.0f; // Store current angle of arrow static float Top = 0.0f; // Stores Top position of arrow static float Length = 0.0f; // Stores Length of arrow if(v_DropState) { Top = 10.0f - (float)v_Start; // Calc Top of arrow Length = ((float)v_End - (float)v_Start); // Calc Bottom of arrow B = 1.0f; // Set to full brightness }else{ if(B > 0.0f) B -= 0.01f; // Slow Brightness decay if(Length > 0.0f) { Top -= 0.5f; Length -= 0.5f; // Arrow recoil }//if }//if - else Angle += 10.0f; //Draw arrow glDisable(GL_LIGHTING); glEnable(GL_BLEND); glDisable(GL_TEXTURE_2D); // Enable Texture Mapping glLoadIdentity(); glTranslatef(0.0f, Top, -32.0f); glRotatef(Angle, 0.0f, 1.0f, 0.0f); glBegin(GL_TRIANGLES); glColor3f(0.0f, 0.0f, 0.0f);glVertex3f(-2.0f, 0.0f, 0.0f); glColor3f(B, B, B);glVertex3f( 0.0f, 0.0f - Length, 0.0f); glColor3f(0.0f, 0.0f, 0.0f);glVertex3f( 2.0f, 0.0f, 0.0f); glEnd(); glEnable(GL_TEXTURE_2D); // Enable Texture Mapping glEnable(GL_LIGHTING); }// RenderDropArrow //---------------------------------------------------------------------------------------- // Description : Draws a star at x,y,z //---------------------------------------------------------------------------------------- void OpenGL :: DrawStar(float v_x, float v_y, float v_z) { static float Clr[3] = {1.0f, 0.0f, 1.0f}; // 3 color values static float ClrInc[3] = {0.000001f, 0.000002f, 0.000003f}; // increment speed of each color float zClr = 0.0f; // Color cycle for(int n = 0; n < 3; n++) { Clr[n] = Clr[n] + ClrInc[n]; if(Clr[n] > 1.0f) { Clr[n] = 1.0f; ClrInc[n] = -ClrInc[n]; }//if if(Clr[n] < 0.5f) { Clr[n] = 0.5f; ClrInc[n] = -ClrInc[n]; }//if }//for //glColor4ub((char)(v_z * 2.0f), 0, 0, 255); zClr = (-v_z / 10.0f); glColor3f(Clr[0] / zClr, Clr[1] / zClr, Clr[2] / zClr); glTranslatef(v_x, v_y, v_z); glEnable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); // Enable Texture Mapping glBindTexture(GL_TEXTURE_2D, Texture[12]); glBegin(GL_QUADS); //glNormal3f( 0.0f, 0.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f,-0.5f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f,-0.5f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f, 0.5f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.0f); glEnd(); }//end DrawStar //---------------------------------------------------------------------------------------- // Description : Displays a moving starfield //---------------------------------------------------------------------------------------- void OpenGL :: RenderStarField() { if(!StarFieldActive) return; static float rotz = 0.0f; static int current_z = 0; int n = 0; if(SFTmr.CheckFreq(30.0f)) { current_z++; rotz += 0.2f; }//if if(current_z >= NUMBER_OF_STARS) current_z = 0; float z = 0.0f; for(n = current_z; n < NUMBER_OF_STARS; n++) { z -= 0.5f; glLoadIdentity(); glRotatef(rotz, 0.0f, 0.0f, 1.0f); DrawStar(StarField[n].x, StarField[n].y, z); }//for for(n = 0; n < current_z; n++) { z -= 0.5f; glLoadIdentity(); glRotatef(rotz, 0.0f, 0.0f, 1.0f); DrawStar(StarField[n].x, StarField[n].y, z); }//for }//end RenderStarField //---------------------------------------------------------------------------------------- // Description : Sets fullscreen status (true/false) //---------------------------------------------------------------------------------------- void OpenGL :: SetFullScreen(bool v_FullScreen) { FullScreen = v_FullScreen; }// SetFullScreen //---------------------------------------------------------------------------------------- // Description : Returns fullscreen status (true/false) //---------------------------------------------------------------------------------------- bool OpenGL :: GetFullScreen() const { return FullScreen; }// GetFullScreen //---------------------------------------------------------------------------------------- // Description : Returns GDI Device Context //---------------------------------------------------------------------------------------- HDC OpenGL :: GethDC() const { return hDC; }// GethDC //---------------------------------------------------------------------------------------- // Description : Returns Window Handle //---------------------------------------------------------------------------------------- HWND OpenGL :: GethWnd() const { return hWnd; }// GethWnd //---------------------------------------------------------------------------------------- // Description : Resize and Initialize the GL Window //---------------------------------------------------------------------------------------- GLvoid OpenGL :: ReSizeGLScene(GLsizei width, GLsizei height) { if(!height) // Prevent A Divide By Zero By height = 1; // Making Height Equal One glViewport(0, 0, width, height); // Reset The Current Viewport glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix }// ReSizeGLScene //---------------------------------------------------------------------------------------- // Description : Properly kill the window //---------------------------------------------------------------------------------------- GLvoid OpenGL :: KillGLWindow() { ShowCursor(true); // Show Mouse Pointer if (FullScreen) // Are We In Fullscreen Mode? { ChangeDisplaySettings(NULL, 0); // If So Switch Back To The Desktop }//if if (hRC) // Do We Have A Rendering Context? { if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts? ErrorMsg("Release of DC and RC failed."); if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? ErrorMsg("Release Rendering Context failed."); hRC = NULL; // Set RC To NULL }//if if (hDC && !ReleaseDC(hWnd, hDC)) // Are We Able To Release The DC { ErrorMsg("Release Device Context failed."); hDC = NULL; // Set DC To NULL }//if if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window? { ErrorMsg("Could not release hWnd."); hWnd = NULL; // Set hWnd To NULL }//if if (!UnregisterClass("OpenGL", hInstance)) // Are We Able To Unregister Class { ErrorMsg("Could Not Unregister Class."); hInstance=NULL; // Set hInstance To NULL }//if }// KillGLWindow //---------------------------------------------------------------------------------------- // Description : Creates the OpenGL Window // // Parameters : // title - Title to appear at the top of the window. // width - Width of the GL Window or fullscreen mode. // height - Height of the GL Window or fullscreen mode. // bits - Number of bits to use for color (8/16/24/32). // fullscreenflag - Pass (true) for Fullscreen Mode or (false) for Windowed Mode. //---------------------------------------------------------------------------------------- bool OpenGL :: CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) { GLuint PixelFormat; // Holds the results after searching for a match WNDCLASS wc; // Windows Class Structure DWORD dwExStyle; // Window Extended Style DWORD dwStyle; // Window Style RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values WindowRect.left = (long)0; // Set Left Value To 0 WindowRect.right = (long)width; // Set Right Value To Requested Width WindowRect.top = (long)0; // Set Top Value To 0 WindowRect.bottom = (long)height; // Set Bottom Value To Requested Height FullScreen = fullscreenflag; // Set The Global Fullscreen Flag hInstance = GetModuleHandle(NULL); // Grab an instance for our window wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw on size, and own dc for window. wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages wc.cbClsExtra = 0; // No extra window data wc.cbWndExtra = 0; // No extra window data wc.hInstance = hInstance; // Set the instance wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load the default icon wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the arrow pointer wc.hbrBackground = NULL; // No background required for GL wc.lpszMenuName = NULL; // We don't want a menu wc.lpszClassName = "OpenGL"; // Set the class name if (!RegisterClass(&wc)) // Attempt to register the window class { ErrorMsg("Failed to register the Window Class."); return false; }//if if (FullScreen) // Attempt Fullscreen Mode? { DEVMODE dmScreenSettings; // Device Mode memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Makes sure memory's cleared dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size of the devmode structure dmScreenSettings.dmPelsWidth = width; // Selected Screen Width dmScreenSettings.dmPelsHeight = height; // Selected Screen Height dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN Gets rid of start bar. if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) { // If the mode fails, offer two options. Quit or use windowed mode. if (MessageBox(NULL, "The requested fullscreen mode is not supported by\nyour video card. Use windowed mode instead?", "OpenGL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES) { FullScreen = false; // Windowed Mode Selected. Fullscreen = false } else { MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP); return false; }//if - else }//if }//if if (FullScreen) // Are we still in fullscreen mode? { dwExStyle=WS_EX_APPWINDOW; // Window Extended Style dwStyle=WS_POPUP; // Windows Style ShowCursor(false); // Hide Mouse Pointer } else { dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style }//if - else AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle); // Adjust window to true requested size // Create The Window if (!(hWnd=CreateWindowEx( dwExStyle, // Extended style for the window "OpenGL", // Class Name title, // Window Title dwStyle | // Defined Window Style WS_CLIPSIBLINGS | // Required Window Style WS_CLIPCHILDREN, // Required Window Style 0, 0, // Window Position WindowRect.right-WindowRect.left, // Calculate Window Width WindowRect.bottom-WindowRect.top, // Calculate Window Height NULL, // No Parent Window NULL, // No Menu hInstance, // Instance NULL))) // Don't pass anything to WM_CREATE { KillGLWindow(); ErrorMsg("Window Creation Error."); return false; }//if static PIXELFORMATDESCRIPTOR pfd= // pfd Tells windows how we want things to be { sizeof(PIXELFORMATDESCRIPTOR), // Size of this Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format bits, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored 0, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 16, // 16Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored };//End static if (!(hDC = GetDC(hWnd))) // Did we get a device context? { KillGLWindow(); // Reset The Display ErrorMsg("Can't create a GL device context."); return false; }//if if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) // Did windows find a matching pixel format? { KillGLWindow(); // Reset The Display ErrorMsg("Can't find a suitable pixel format."); return false; }//if if(!SetPixelFormat(hDC, PixelFormat, &pfd)) // Are we able to set the pixel format? { KillGLWindow(); // Reset The Display ErrorMsg("Can't set the pixel format."); return false; }//if if (!(hRC = wglCreateContext(hDC))) // Are We Able To Get A Rendering Context? { KillGLWindow(); // Reset The Display ErrorMsg("Can't create a GL Rendering Context."); return false; }//if if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context { KillGLWindow(); // Reset The Display ErrorMsg("Can't activate the GL Rendering Context."); return false; }//if ShowWindow(hWnd,SW_SHOW); // Show The Window SetForegroundWindow(hWnd); // Slightly Higher Priority SetFocus(hWnd); // Sets Keyboard Focus To The Window ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen if (!InitGL()) // Initialize Our Newly Created GL Window { KillGLWindow(); // Reset The Display ErrorMsg("Initialization Failed."); return false; }//if return true; //No errors occured return true }// CreateGLWindow //---------------------------------------------------------------------------------------- // Description : Loads a bitmap file and returns a pointer to the bitmap data // // Parameters : // Filename - name and path of a bitmap file eg. (path/file.bmp) //---------------------------------------------------------------------------------------- AUX_RGBImageRec* OpenGL :: LoadBMP(char *Filename) { FILE *File = NULL; // File Handle if (!Filename) // Make Sure A Filename Was Given return NULL; // If Not Return NULL File = fopen(Filename, "r"); // Check To See If The File Exists if (File) // Does The File Exist? { fclose(File); // Close The Handle return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer }//if return NULL; // If Load Failed Return NULL }// LoadBMP //---------------------------------------------------------------------------------------- // Description : Loads all the required OpenGL textures into memory //---------------------------------------------------------------------------------------- bool OpenGL :: LoadGLTextures() // Load Bitmaps And Convert To Textures { bool Status = FALSE; // Status Indicator int loop1 = 0; AUX_RGBImageRec *TextureImage[NUMBER_OF_TEXTURES]; // Create Storage Space For The Textures memset(TextureImage,0,sizeof(void *)*NUMBER_OF_TEXTURES); // Set The Pointer To NULL if ((TextureImage[0]=LoadBMP("data/0.bmp")) && (TextureImage[1]=LoadBMP("data/1.bmp")) && (TextureImage[2]=LoadBMP("data/2.bmp")) && (TextureImage[3]=LoadBMP("data/3.bmp")) && (TextureImage[4]=LoadBMP("data/4.bmp")) && (TextureImage[5]=LoadBMP("data/5.bmp")) && (TextureImage[6]=LoadBMP("data/6.bmp")) && (TextureImage[7]=LoadBMP("data/7.bmp")) && (TextureImage[8]=LoadBMP("data/8.bmp")) && (TextureImage[9]=LoadBMP("data/9.bmp")) && (TextureImage[10]=LoadBMP("data/10.bmp")) && (TextureImage[11]=LoadBMP("data/11.bmp")) && (TextureImage[12]=LoadBMP("data/12.bmp")) && (TextureImage[13]=LoadBMP("data/13.bmp"))) { Status=TRUE; // Set The Status To TRUE glGenTextures(NUMBER_OF_TEXTURES, &Texture[0]); // Create The Texture for (loop1=0; loop1<NUMBER_OF_TEXTURES; loop1++) // Loop Through Textures { // Create MipMapped Texture glBindTexture(GL_TEXTURE_2D, Texture[loop1]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[loop1]->sizeX, TextureImage[loop1]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop1]->data); }//for for (loop1=0; loop1<NUMBER_OF_TEXTURES; loop1++) // Loop Through Textures { if (TextureImage[loop1]) // If Texture Exists { if (TextureImage[loop1]->data) // If Texture Image Exists free(TextureImage[loop1]->data); // Free The Texture Image Memory free(TextureImage[loop1]); // Free The Image Structure }//if }//for }//if return Status; // Return The Status }// LoadGLTextures //---------------------------------------------------------------------------------------- // Description : Adjust Base Start Pos //---------------------------------------------------------------------------------------- void OpenGL :: SetTextBase(int Base) { fStartPos = Base; }// SetTextBase //---------------------------------------------------------------------------------------- // Description : Loads the font data into memory //---------------------------------------------------------------------------------------- GLvoid OpenGL :: LoadFont() // Build Our Font Display List { AUX_RGBImageRec *Texs[1]; // Set Font Texture, How Many Characters per row and how many columns fxCount = 16; fyCount = 16; Texs[0] = NULL; Texs[0] = auxDIBImageLoad("data/font.bmp"); // Load Font Texture if (!Texs[0]) ErrorMsg("Texture not loaded"); fTexture[0] = NULL; glGenTextures(1, &fTexture[0]); // Create Font Texture glBindTexture(GL_TEXTURE_2D, fTexture[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, Texs[0]->sizeX , Texs[0]->sizeY , 0, GL_RGB, GL_UNSIGNED_BYTE, Texs[0]->data); if(Texs[0]->data != NULL) free(Texs[0]->data); // Free Data Allocated // Set Font Width and Font Height in Texture, and Character Spacing fWidth = 16; fHeight = 16; fSpacing = 10; // Adjust Fonts 2D Drawing Rectangle Size fdWidth = 640; fdHeight = 480; int loop; float cx; // Holds Our X Character Coord float cy; // Holds Our Y Character Coord float cwx; // CharWidth in texture units float cwy; // CharHeight in texture units cwx = (1.0f / 256.0f) * fWidth; cwy = (1.0f / 256.0f) * fHeight; fBase = glGenLists(fxCount * fyCount); // Creating Display Lists glBindTexture(GL_TEXTURE_2D, fTexture[0]); // Select Our Font Texture for (loop = 0; loop < (fxCount * fyCount); loop++) // Loop Through All Lists { cx = float(loop % fxCount) * cwx; // X Position Of Current Character cy = float(loop / fyCount) * cwy; // Y Position Of Current Character glNewList(fBase + loop,GL_COMPILE); // Start Building A List glBegin(GL_QUADS); // Use A Quad For Each Character glTexCoord2f(cx, 1 - cy - cwy); // Texture Coord (Bottom Left) glVertex2i(0, 0); // Vertex Coord (Bottom Left) glTexCoord2f(cx + cwx, 1 - cy - cwy); // Texture Coord (Bottom Right) glVertex2i(fWidth - 1,0); // Vertex Coord (Bottom Right) glTexCoord2f(cx + cwx, 1 - cy); // Texture Coord (Top Right) glVertex2i(fWidth - 1,fHeight - 1); // Vertex Coord (Top Right) glTexCoord2f(cx, 1 - cy); // Texture Coord (Top Left) glVertex2i(0, fHeight - 1); // Vertex Coord (Top Left) glEnd(); // Done Building Our Quad (Character) glTranslated(fSpacing, 0, 0); // Move To The Right Of The Character glEndList(); // Done Building The Display List }//for // Loop Until All Are Built }// LoadFont //---------------------------------------------------------------------------------------- // Description : Displays text on screen at x,y position //---------------------------------------------------------------------------------------- GLvoid OpenGL :: Print(GLint x, GLint y, const char *fmt, ...) // Where The Printing Happens { char text[256]; // Holds Our String va_list ap; // Pointer To List Of Arguments if (fmt == NULL) // If There's No Text return; // Do Nothing va_start(ap, fmt); // Parses The String For Variables vsprintf(text, fmt, ap); // And Converts Symbols To Actual Numbers va_end(ap); // Results Are Stored In Text glBindTexture(GL_TEXTURE_2D, fTexture[0]); // Select Our Font Texture glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); // Disables Depth Testing glDisable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glPushMatrix(); // Store The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix glOrtho(0,fdWidth,0,fdHeight,-1,1); // Set Up An Ortho Screen glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glPushMatrix(); // Store The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix glTranslated(x,fdHeight - y,0); // Position The Text (0,0 - Bottom Left) glListBase(fBase - fStartPos); // Choose The Font Set (0 or 1) glCallLists(strlen(text),GL_BYTE,text); // Write The Text To The Screen glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glPopMatrix(); // Restore The Old Projection Matrix glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix //Reset Old settings glPopMatrix(); // Restore The Old Projection Matrix glEnable(GL_LIGHTING); glEnable(GL_BLEND); }// glPrint